package com.bjc.platform.model;

/***********************************************************************
 * Module:  AdmOrg.java
 * Author:  Administrator
 * Purpose: Defines the Class AdmOrg
 ***********************************************************************/

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.fasterxml.jackson.annotation.JsonBackReference;

/**
 * 组织
 * 
 **/
@Entity
@Table(name = "adm_org")
public class AdmOrg implements Serializable {

	private static final long serialVersionUID = 5329273198312815647L;

	private Long id;
	private String name;
	private AdmOrg parent;
	private String contact;
	private String contactPhone;
	private String remark;
	private String address;
	private Date setupDate; // 组织成立时间
	private String orgnizeType;
	private AdmDepartmentType orgSubType;
	private String code;
	private Long sort;
	private Long creator;
	private Date createTime;
	private Long updater;
	private Date updateTime;
	private Boolean flag;
	private Long companyId;

	private Set<AdmOrg> children;

	public AdmOrg(Long id) {
		this.id = id;
	}

	public AdmOrg() {
	}

	@Id
	@Column(name = "id", columnDefinition="int")
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = true)
	@JoinColumn(name = "parent_id")
	public AdmOrg getParent() {
		return parent;
	}

	public void setParent(AdmOrg parent) {
		this.parent = parent;
	}

	public String getContact() {
		return contact;
	}

	public void setContact(String contact) {
		this.contact = contact;
	}

	@Column(name = "contact_phone")
	public String getContactPhone() {
		return contactPhone;
	}

	public void setContactPhone(String contactPhone) {
		this.contactPhone = contactPhone;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Column(name = "setup_date")
	public Date getSetupDate() {
		return setupDate;
	}

	public void setSetupDate(Date setupDate) {
		this.setupDate = setupDate;
	}

	@ManyToOne(optional = true)
	@JoinColumn(name = "org_sub_type")
	public AdmDepartmentType getOrgSubType() {
		return orgSubType;
	}

	public void setOrgSubType(AdmDepartmentType orgSubType) {
		this.orgSubType = orgSubType;
	}

	@Column(name = "org_type")
	public String getOrgnizeType() {
		return orgnizeType;
	}

	public void setOrgnizeType(String orgnizeType) {
		this.orgnizeType = orgnizeType;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	@Column(columnDefinition="int")
	public Long getSort() {
		return sort;
	}

	public void setSort(Long sort) {
		this.sort = sort;
	}

	@Column(columnDefinition="int")
	public Long getCreator() {
		return creator;
	}

	public void setCreator(Long creator) {
		this.creator = creator;
	}

	@Column(name = "create_time")
	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	@Column(columnDefinition="int")
	public Long getUpdater() {
		return updater;
	}

	public void setUpdater(Long updater) {
		this.updater = updater;
	}

	@Column(name = "update_time")
	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	@Column(name = "flag", nullable = false)
	public Boolean isFlag() {
		return this.flag;
	}

	public void setFlag(Boolean flag) {
		this.flag = flag;
	}
	
	@Column(name="company_id", columnDefinition="int")
	public Long getCompanyId() {
		return companyId;
	}

	public void setCompanyId(Long companyId) {
		this.companyId = companyId;
	}

	@JsonBackReference
	@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "parent", fetch = FetchType.LAZY)
	public Set<AdmOrg> getChildren() {
		return children;
	}

	public void setChildren(Set<AdmOrg> children) {
		this.children = children;
	}

	@Transient
	public String getBelongOrg() {
		AdmOrg p = parent;
		List<String> names = new ArrayList<String>();
		StringBuilder buf = new StringBuilder();
		while (p != null) {
			names.add(p.getName());
			p = p.getParent();
		}

		for (int i = names.size() - 1; i >= 0; i--) {
			buf.append(names.get(i));
			if (i > 0) {
				buf.append("->");
			}
		}

		return buf.toString();
	}
	
	/** 返回公司下的组织
	 * @return
	 */
	@Transient
	public String getOrgDescForCompany() {
		AdmOrg p = parent;
		List<String> names = new ArrayList<String>();
		names.add(this.name);
		StringBuilder buf = new StringBuilder();
		while (p != null && !"GROUP".equals(p.getOrgnizeType())) {
			names.add(p.getName());
			p = p.getParent();
		}

		for (int i = names.size() - 1; i >= 0; i--) {
			buf.append(names.get(i));
			if (i > 0) {
				buf.append("->");
			}
		}

		return buf.toString();
	}

	/**
	 * 获取当前组织所在的公司
	 * 
	 * @return
	 */
	@JsonBackReference
	@Transient
	public AdmOrg getCompany() {
		if ("COMPANY".equals(this.orgnizeType)) {
			return this;
		} else {
			AdmOrg p = parent;
			while (p != null) {
				if ("COMPANY".equals(p.getOrgnizeType())) {
					return p;
				} else {
					p = p.getParent();
				}
			}

		}
		return null;
	}

	/**
	 * 获取当前组织所在的公司
	 * 
	 * @return
	 */
	@JsonBackReference
	@Transient
	public List<AdmOrg> getAllChildren() {
		List<AdmOrg> orgs = new ArrayList<AdmOrg>();
		if (this.getChildren() != null) {
			orgs.addAll(this.getChildren());
			for (AdmOrg org : this.getChildren()) {
				getChildrens(orgs, org);
			}
		}
		return orgs;
	}

	private void getChildrens(List<AdmOrg> orgs, AdmOrg org) {
		if (org != null && org.getChildren() != null) {
			orgs.addAll(org.getChildren());
			for (AdmOrg o : org.getChildren()) {
				getChildrens(orgs, o);
			}
		}
	}
}